import { renewOSS } from '@/services/api/api-aliyun';
import { getToken } from '@/utils/token';
import { getUUID } from '@/utils/uuid';
import { ProFormUploadButton } from '@ant-design/pro-form';
import { message, Modal, Space, Typography } from 'antd';
import { UploadChangeParam } from 'antd/lib/upload';
import moment from 'moment';
import { useState } from 'react';
const OSS = require('ali-oss');
const isDev = process.env.NODE_ENV === 'development';
// const isDev = true;

interface AliyunOSSUploadProps {
  accountId?: string;
  organizationName?: string;
  action: string;
  value?: Array<string>;
  onChange?: (value: Array<string>) => void;
  onIsUpload: (value: boolean) => void;
}

const AliyunOSSUpload: React.FC<AliyunOSSUploadProps> = ({
  accountId,
  organizationName,
  action,
  value,
  onChange,
  onIsUpload,
}) => {
  const [previewVisible, setPreviewVisibleState] = useState<{
    visible: boolean;
    title: string;
    url: string;
  }>({
    visible: false,
    title: '',
    url: '',
  });

  const onChangeUpload = (info: UploadChangeParam) => {
    if (info.file.status === 'done') {
      const ids = info.fileList.flatMap((item) => {
        if (item.status === 'done') {
          return item.response.Status == 'ok' ? item.response.id : '';
        }
      });
      if (onChange) {
        value = ids;
        onChange(ids);
      }
    }
  };

  const onRemoveUpload = (info: any) => {
    if (info.response == undefined) {
      message.warning('附件正在上传中');
      return false;
    }

    if (onChange) {
      value?.splice(
        value.findIndex((id) => id === info.response.id),
        1,
      );
      onChange(value!);
    }
  };

  const beforeUpload = async (file: any, _fileList: any) => {
    // const isLt5G = file.size / 1024 / 1024 < 5;
    // if (!isLt5G) {
    //   message.error('附件大小不能超过 5GB!');
    // }
    // return isLt5G;
  };

  const customRequest = async (options: any) => {
    const fileType = options.file.type;
    if (
      fileType == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
      fileType == 'application/msword' ||
      fileType == 'application/pdf' ||
      fileType == 'application/kswps' ||
      fileType == 'text/plain'
    ) {
      message.error(
        '为保证小程序使用效果，附件禁止上传.docx、.doc、.wps、.pdf、.txt、.zip、.rar文档',
      );
      options.onError('{"Status":"error"}', options.file);
      return;
    }

    const name = options.file.name.toLowerCase();
    const index1 = name.lastIndexOf('.');
    const index2 = name.length;
    const type = name.substring(index1, index2);

    if (
      type.indexOf('.exe') > -1 ||
      type.indexOf('.msi') > -1 ||
      type.indexOf('.cmd') > -1 ||
      type.indexOf('.sys') > -1 ||
      type.indexOf('.sh') > -1
    ) {
      message.error('不可上传可执行文件或脚本');
      options.onError('{"Status":"不可上传可执行文件或脚本"}', options.file);
      return;
    }

    if (type.indexOf('.zip') > -1 || type.indexOf('.rar') > -1) {
      message.error('为保证小程序使用效果，附件禁止上传.zip、.rar文档');
      options.onError('{"Status":"error"}', options.file);
      return;
    }

    if (
      type.indexOf('.docx') > -1 ||
      type.indexOf('.doc') > -1 ||
      type.indexOf('.wps') > -1 ||
      type.indexOf('.pdf') > -1 ||
      type.indexOf('.txt') > -1
    ) {
      message.error('为保证小程序使用效果，附件禁止上传.docx、.doc、.wps、.pdf、.txt文档');
      options.onError('{"Status":"error"}', options.file);
      return;
    }

    const isLt5G = options.file.size / 1024 / 1024 / 1024 < 5;

    if (!isLt5G) {
      message.error('附件大小不能超过 5GB!');
      options.onError('{"Status":"error"}', options.file);
      return;
    }

    const response = await renewOSS();

    if (response.code == 0) {
      const headers = {
        'Content-Disposition': 'attachment;',
      };

      const multipartUploadOptions = {
        callback: {
          // 设置回调请求的服务器地址。
          url: action,
          // 设置发起回调时请求body的值。
          body:
            '{"bucket":${bucket}, "object":${object}, "etag":${etag}, "size":${size}, "mimeType":${mimeType}, "satoken":"' +
            getToken() +
            '"}',
          // 设置发起回调请求的Content-Type。
          contentType: 'application/json',
          // 设置发起回调请求的自定义参数。
          // customValue: {
          //   'x:accountId': '我要传递的数据',
          // },
        },
        progress: (p, cpt, res) => {
          onIsUpload(true);
          options.onProgress({ percent: Math.round(p * 100).toFixed(2) }, options.file);
        },
        headers,
      };

      const OSSData = {
        host: !isDev
          ? 'cqgdrm-xtbs.oss-cn-hangzhou.aliyuncs.com'
          : 'cqgdrm-xtbs-test.oss-cn-hangzhou.aliyuncs.com',
        accessKeyId: response.data.accessKeyId,
        accessKeySecret: response.data.accessKeySecret,
        stsToken: response.data.securityToken,
        region: 'oss-cn-hangzhou',
        bucket: !isDev ? 'cqgdrm-xtbs' : 'cqgdrm-xtbs-test',
      };

      const client = new OSS({
        // yourRegion填写Bucket所在地域。以华东1（杭州）为例，Region填写为oss-cn-hangzhou。
        region: 'oss-cn-hangzhou',
        // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
        accessKeyId: OSSData.accessKeyId,
        accessKeySecret: OSSData.accessKeySecret,
        // 从STS服务获取的安全令牌（SecurityToken）。
        stsToken: OSSData.stsToken,
        refreshSTSToken: async () => {
          // 向您搭建的STS服务获取临时访问凭证。
          const response = await renewOSS();
          return {
            accessKeyId: response.data.accessKeyId,
            accessKeySecret: response.data.accessKeySecret,
            stsToken: response.data.securityToken,
          };
        },
        refreshSTSTokenInterval: 300000,
        bucket: OSSData.bucket,
      });

      client
        .multipartUpload(
          `${organizationName}/${moment().format('yyyy-MM-DD')}/${getUUID()}/${options.file.name}`,
          options.file,
          multipartUploadOptions,
        )
        .then((response: any) => {
          if (response.data.Status == 'ok') {
            onIsUpload(false);
            options.onSuccess(response.data, options.file);
          } else {
            onIsUpload(false);
            options.onError(response.data, options.file);
          }
        })
        .catch((e) => {
          onIsUpload(false);
          options.onError('{"Status":"error"}', options.file);
        });
    }
  };

  const handleCancel = () => {
    setPreviewVisibleState({
      visible: false,
      title: '',
      url: '',
    });
  };
  return (
    <>
      <ProFormUploadButton
        label="上传附件（支持多选）"
        max={5}
        fieldProps={{
          maxCount: 5,
          multiple: true,
          // listType: 'picture-card',
          beforeUpload,
          onChange: onChangeUpload,
          customRequest,
          onRemove: onRemoveUpload,
        }}
        extra={
          <Space
            style={{
              paddingTop: '15px',
            }}
          >
            <Typography>
              <Typography.Paragraph>
                <Typography.Text type="secondary">注意事项：</Typography.Text>
              </Typography.Paragraph>
              <Typography.Paragraph>
                <Typography.Text type="secondary">单个附件限制在 5GB 内</Typography.Text>
              </Typography.Paragraph>
              <Typography.Paragraph>
                <Typography.Text type="danger">
                  为保证小程序使用效果，附件禁止上传.docx、.doc、.wps、.pdf、.txt、.zip、.rar文件，请把正文内容复制到上方编辑器中
                </Typography.Text>
              </Typography.Paragraph>
            </Typography>
          </Space>
        }
      />
      <Modal
        visible={previewVisible.visible}
        title={previewVisible.title}
        footer={null}
        onCancel={handleCancel}
      >
        <img alt="example" style={{ width: '100%' }} src={previewVisible.url} />
      </Modal>
    </>
  );
};

export default AliyunOSSUpload;
